import threading

from lxg.SsqSpider import SsqSpider
from lxg.db import SsqDb
from lxg.ssq.red_ball import RedBall
from lxg.ssq.blue_ball import BlueBall

ssqDb = SsqDb()
spider = SsqSpider()


class SsqUtil:
    def __init__(self):
        self.red = RedBall(self.get_curr_red_tuple())
        self.blue = BlueBall(self.get_curr_red_tuple(), self.get_latest_5_blue_tuple())

    def get_next_red_set(self):
        """
        获取下期的红球集合
        :return: 红球集合
        """
        return self.red.get_next_red_num_set()

    def get_next_blue_set(self):
        """
        获取下期的篮球集合
        :return: 篮球集合
        """
        return self.blue.get_next_blue_ball_num_set()

    def get_public_num_red_set(self, public_num):
        """
        获取指定期数的红球集合
        :param public_num: 开奖期数
        :return: 红球集合
        """
        red = RedBall(self.get_red_tuple_by_public_num_tuple(public_num))
        return red.get_next_red_num_set()

    def get_public_num_blue_set(self, public_num):
        """
        获取指定期数的篮球集合
        :param public_num: 指定期数
        :return: 篮球集合
        """
        blue = BlueBall(
            self.get_red_tuple_by_public_num_tuple(public_num),
            self.get_before_5_blue_tuple_by_public_num(public_num)
        )
        return blue.get_next_blue_ball_num_set()

    def need_init(self):
        """
        是否需要重新初始化爬虫
        """
        web_total_size = spider.get_total_page_size()
        database_total_size = ssqDb.count()
        print('网页中的数据总数: ', web_total_size)
        print('数据库中的数据总数: ', database_total_size)
        return web_total_size > database_total_size

    def init(self):
        """
        更新数据库中的数据
        """
        if self.need_init():
            print('有新的数据需要更新到数据库')
            for ssq_tuple in spider.run():
                if not ssqDb.is_exists(ssq_tuple[0]):
                    ssqDb.add_by_tuple(ssq_tuple)
                    print("数据插入成功:{}".format(ssq_tuple))
                    if not self.need_init():  # 优化
                        break

    def count(self):
        """
        获取数据库中的总记录数
        """
        return ssqDb.count()

    def all(self):
        """
        获取数据库中的所有双色球数据
        """
        return ssqDb.all()

    def page(self, page, size=20):
        """
        根据分页参数获取页面数据
        :param page: 第几页
        :param size: 每页数量,默认20
        :return: 分页数据集合
        """
        # self.init()  # 更新数据
        threading.Thread(target=self.init()).start()
        return ssqDb.page(page, size)

    def get_curr_red_tuple(self):
        """
        获取本期的红球球数据
        """
        return ssqDb.get_latest_red_tuple()

    def get_latest_5_blue_tuple(self):
        """
        获取最新五期的篮球数据
        """
        return ssqDb.get_latest_5_blue_tuple()

    def get_red_tuple_by_public_num_tuple(self, public_num):
        """
        根据指定的开奖期号获取红球元组
        :param public_num: 开奖期号
        """
        return ssqDb.get_red_tuple_by_public_num_tuple(public_num)

    def get_before_5_blue_tuple_by_public_num(slef, public_num):
        """
        根据指定的开奖期号获取之前5期的篮球数据
        :param public_num: 开奖期号
        """
        return ssqDb.get_before_5_blue_tuple_by_public_num(public_num)

    def get_public_num_all(self):
        """
        获取数据库中所有的期号
        """
        public_num_list = ssqDb.get_public_num_all()
        print(public_num_list)
        public_num_list = list(map(lambda x: {'value': str(x[0]), 'label': x[1]}, public_num_list))
        return public_num_list

    def get_ball_data(self, id):
        """
        根据ID获取红球和篮球中奖数据和预测数据
        :param id: ID
        """
        database_ball = ssqDb.get_ball_data_by_id(id)
        public_num = database_ball[0]  # 期号
        # 根据期号预测
        next_red_ball = self.get_public_num_red_set(public_num)
        next_blue_ball = self.get_public_num_blue_set(public_num)
        # 整合数据
        ball = {}
        ball['curr'] = {
            'red': list(map(lambda x: int(x), database_ball[1].split(','))),
            'blue': int(database_ball[2])
        }
        ball['next'] = {
            'red': list(next_red_ball),
            'blue': list(next_blue_ball)
        }
        # 返回数据
        return ball

    def get_next_all_predication(self, num=20):
        """从预测号码中随机生成20个号码"""
        blue_set = self.get_next_blue_set()  # 篮球集合
        red_set = self.get_next_red_set()  # 红球集合
        # 组合20个可能性并去重 6个红球+1个篮球
        next_num_list = []
        while len(next_num_list) < num + 1:
            next_red_set = set()
            import random
            while len(next_red_set) < 7:
                next_red_set.add(random.choice(list(red_set)))
            next_blue = random.choice(list(blue_set))
            # 拼接
            next_num_list.append({
                'red': next_red_set,
                'blue': next_blue
            })
        return next_num_list


if __name__ == '__main__':
    su = SsqUtil()
    print(su.get_next_all_predication())
